import { getEnv } from '@/shared/utils/env';
import { HubConnectionBuilder, HubConnection, HubConnectionState } from '@microsoft/signalr';
import { useUserStoreWithOut } from '@shared/store/user';
import {
  SocketEvent,
  SocketEventType,
  productNotifyProperties,
  deepProductNotifyProperties,
  tasksProperties,
  deleteTaskProperties
} from './type';
import { emitter } from '@main/utils/mitt';
import logger from '@shared/utils/logger';

let connection: HubConnection | null = null;

export async function socketConnect() {
  if (getConnectionState() === HubConnectionState.Disconnected) {
    await socketRetryConnection();
    return;
  }

  const url = new URL('/hubs/producthub', getEnv().RENDERER_VITE_DEFAULT_REQUEST_URL);

  connection = new HubConnectionBuilder()
    .withUrl(url.toString(), {
      accessTokenFactory: async () => await getToken()
    })
    .withAutomaticReconnect([0, 2000, 10000, 30000])
    .build();

  initSocketEvent(connection);

  return await connection
    .start()
    .then(() => {
      logger.info('----- socketConnect fn >>> socket connected 建立连接成功 -----');
    })
    .catch((error) => {
      logger.error('----- socketConnect fn >>> socket connect error 建立连接失败 -----', error);
    });
}

export async function getToken() {
  const userStore = useUserStoreWithOut();
  return (await userStore.getEfficaciousToken())?.access_token ?? '';
}

export function getConnectionState() {
  if (!connection) {
    return;
  }

  return connection.state;
}

// 连接一次
export async function socketRetryConnection() {
  return await connection?.start();
}

// 断开连接
export async function socketDisconnect() {
  if (!connection) {
    return;
  }
  await connection.stop();
}

// 销毁
export async function socketDestroy() {
  if (!connection) {
    return;
  }
  await socketDisconnect();
  connection = null;
}

const initSocketEvent = (connection: HubConnection) => {
  connection.on('ReceiveMessage', (message: string) => {
    logger.info('----- initSocketEvent fn >>> socket ReceiveMessage 事件行为触发 -----', message);
    handleSocketMessage(JSON.parse(message) as SocketEvent);
  });

  connection.onclose(() => {
    logger.info('----- initSocketEvent fn >>> socket onclose 连接关闭事件行为触发 -----');
  });

  connection.onreconnecting((error) => {
    logger.info(
      '----- initSocketEvent fn >>> socket onclose 尝试重新连接事件行为触发 -----',
      error
    );
  });

  connection.onreconnected((connectionId) => {
    logger.info(
      '----- initSocketEvent fn >>> socket onclose 连接关闭事件行为触发 -----',
      connectionId
    );
  });
};

const handleSocketMessage = (message: SocketEvent) => {
  switch (message.event_type) {
    case SocketEventType.productNotify:
    case SocketEventType.deepProductNotify:
      handleReceiveProductSuccess(message.product_id, message.data);
      break;
    case SocketEventType.receiveTaskNotify:
      handleReceiveTask(message.data);
      break;
    case SocketEventType.deleteTaskNotify:
      handleReceiveDeleteTask(message.data);
      break;
    default:
      break;
  }
};

const handleReceiveProductSuccess = (
  product_id: number,
  data: productNotifyProperties | deepProductNotifyProperties
) => {
  emitter.emit('product-handle-reply', { product_id, ...data });
};

const handleReceiveTask = (data: tasksProperties) => {
  emitter.emit('receive-task', data);
};

const handleReceiveDeleteTask = (data: deleteTaskProperties) => {
  emitter.emit('delete-task', data);
};
